"""
通知服务 - 邮件通知和WebSocket推送
"""

import asyncio
import aiosmtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import List, Dict, Any, Optional
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select

from app.config import settings
from app.utils.logger import get_monitor_logger
from app.models.user import User
from app.models.notification import Notification
from app.schemas.notification import NotificationCreate
from app.services.telegram_service import TelegramService


class NotificationService:
    """通知服务类"""
    
    def __init__(self):
        # 邮件配置
        self.smtp_host = settings.SMTP_HOST
        self.smtp_port = settings.SMTP_PORT
        self.smtp_user = settings.SMTP_USER
        self.smtp_password = settings.SMTP_PASSWORD

        # 微信公众号配置 (占位)
        self.wechat_app_id = getattr(settings, 'WECHAT_APP_ID', None)
        self.wechat_app_secret = getattr(settings, 'WECHAT_APP_SECRET', None)
        self.wechat_access_token = None  # 动态获取

        self.logger = get_monitor_logger()
        
        # Telegram服务
        self.telegram_service = TelegramService()
    
    async def send_email(self, to_email: str, subject: str, content: str, is_html: bool = True) -> bool:
        """发送邮件"""

        max_retries = 3
        retry_delay = 2

        for attempt in range(max_retries):
            try:
                if attempt > 0:
                    self.logger.info(f"📧 邮件发送重试 {attempt}/{max_retries-1}: {to_email}")
                    await asyncio.sleep(retry_delay * attempt)  # 递增延迟

                # self.logger.info(f"📧 开始发送邮件到: {to_email}")
                # self.logger.info(f"📧 邮件主题: {subject}")
                # self.logger.info(f"📧 SMTP配置: {self.smtp_host}:{self.smtp_port}")

                # 创建邮件消息
                message = MIMEMultipart("alternative")
                message["Subject"] = subject
                message["From"] = self.smtp_user
                message["To"] = to_email

                # 添加邮件内容
                if is_html:
                    part = MIMEText(content, "html", "utf-8")
                else:
                    part = MIMEText(content, "plain", "utf-8")

                message.attach(part)

                # 发送邮件
                # self.logger.info(f"📧 连接SMTP服务器: {self.smtp_host}:{self.smtp_port}")

                # 创建SMTP客户端，增加重试和超时配置
                smtp_client = aiosmtplib.SMTP(
                    hostname=self.smtp_host,
                    port=self.smtp_port,
                    start_tls=False,  # 不自动启用TLS
                    timeout=30,  # 增加超时时间
                    use_tls=False,  # 先不使用TLS，通过start_tls启用
                )

                # 手动连接和发送，增加错误处理
                try:
                    await smtp_client.connect()
                    await smtp_client.starttls()  # 手动启用TLS
                    await smtp_client.login(self.smtp_user, self.smtp_password)
                    await smtp_client.send_message(message)
                finally:
                    try:
                        await smtp_client.quit()
                    except:
                        pass  # 忽略quit时的错误

                self.logger.info(f"✅ 邮件发送成功: {to_email}")
                return True

            except Exception as e:
                self.logger.error(f"❌ 邮件发送失败 (尝试 {attempt+1}/{max_retries}): {e}")

                if attempt == max_retries - 1:
                    # 最后一次尝试失败，记录详细错误
                    self.logger.error(f"❌ 错误详情: {type(e).__name__}: {str(e)}")
                    import traceback
                    self.logger.error(f"❌ 邮件发送堆栈: {traceback.format_exc()}")
                    return False

                # 继续重试
                continue

        return False
    
    async def send_product_notification(self, user_email: str, products: List[Dict[str, Any]],
                                      notification_subject: str, monitor_type: str = "keyword") -> bool:
        """发送商品通知邮件"""
        if monitor_type == "seller":
            subject = f"🔥 煤炉卖家上新提醒 - {notification_subject}"
        elif monitor_type == "shop":
            subject = f"🔥 煤炉店铺上新提醒 - {notification_subject}"
        else:
            subject = f"🔥 煤炉关键词上新提醒 - {notification_subject}"

        # 根据监控类型构建不同的标题和描述
        if monitor_type == "seller":
            page_title = "煤炉卖家上新提醒"
            header_title = "🔥 煤炉卖家上新提醒"
            description_label = "卖家"
        elif monitor_type == "shop":
            page_title = "煤炉店铺上新提醒"
            header_title = "🔥 煤炉店铺上新提醒"
            description_label = "店铺"
        else:
            page_title = "煤炉关键词上新提醒"
            header_title = "🔥 煤炉关键词上新提醒"
            description_label = "关键词"

        # 构建HTML邮件内容
        html_content = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="utf-8">
            <title>{page_title}</title>
            <style>
                body {{ font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; }}
                .container {{ max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; }}
                .header {{ text-align: center; color: #ff6b35; margin-bottom: 20px; }}
                .product {{ border: 1px solid #ddd; margin: 15px 0; padding: 15px; border-radius: 8px; display: flex; align-items: flex-start; gap: 15px; }}
                .product-image {{ flex-shrink: 0; }}
                .product-image img {{ width: 120px; height: 120px; object-fit: cover; border-radius: 6px; border: 1px solid #eee; }}
                .product-info {{ flex: 1; }}
                .product-title {{ font-weight: bold; color: #333; margin-bottom: 8px; font-size: 16px; line-height: 1.4; }}
                .product-price {{ color: #ff6b35; font-size: 20px; font-weight: bold; margin-bottom: 10px; }}
                .product-link {{ color: #007bff; text-decoration: none; padding: 8px 16px; background-color: #f8f9fa; border: 1px solid #007bff; border-radius: 4px; display: inline-block; }}
                .product-link:hover {{ background-color: #007bff; color: white; }}
                .no-image {{ width: 120px; height: 120px; background-color: #f8f9fa; border: 1px solid #ddd; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: #666; font-size: 12px; text-align: center; }}
                .footer {{ text-align: center; margin-top: 20px; color: #666; font-size: 12px; }}
                @media (max-width: 480px) {{
                    .product {{ flex-direction: column; }}
                    .product-image img, .no-image {{ width: 100%; max-width: 200px; margin: 0 auto; }}
                }}
            </style>
        </head>
        <body>
            <div class="container">
                <div class="header">
                    <h1>{header_title}</h1>
                    <p>{description_label}: <strong>{notification_subject}</strong></p>
                </div>

                <p>发现 <strong>{len(products)}</strong> 个新商品：</p>
        """
        
        # 添加商品信息
        for product in products:
            # 获取商品图片URL - 支持多种字段名
            image_url = None
            if product.get('image_url'):
                image_url = product.get('image_url')
            elif product.get('thumbnail'):
                image_url = product.get('thumbnail')
            elif isinstance(product.get('thumbnails'), list) and len(product.get('thumbnails', [])) > 0:
                image_url = product.get('thumbnails')[0]

            # 构建图片部分
            if image_url:
                image_html = f'<div class="product-image"><img src="{image_url}" alt="商品图片" onerror="this.parentElement.innerHTML=\'<div class=&quot;no-image&quot;>暂无图片</div>\'"></div>'
            else:
                image_html = '<div class="product-image"><div class="no-image">暂无图片</div></div>'

            html_content += f"""
                <div class="product">
                    {image_html}
                    <div class="product-info">
                        <div class="product-title">{product.get('name', '未知商品')}</div>
                        <div class="product-price">¥{product.get('price', 0)}</div>
                        <a href="{product.get('url', '#')}" class="product-link" target="_blank">查看详情</a>
                    </div>
                </div>
            """
        
        html_content += """
                <div class="footer">
                    <p>煤炉监控系统 - 实时为您监控商品上新</p>
                    <p>如不想继续接收通知，请登录系统关闭监控</p>
                </div>
            </div>
        </body>
        </html>
        """

        return await self.send_email(user_email, subject, html_content, is_html=True)

    async def send_wechat_notification(self, user_openid: str, products: List[Dict[str, Any]],
                                     notification_subject: str, monitor_type: str = "keyword") -> bool:
        """
        发送微信公众号通知

        Args:
            user_openid: 用户微信OpenID
            products: 商品列表
            notification_subject: 通知主题（关键词或卖家信息）
            monitor_type: 监控类型（keyword/seller/shop）

        Returns:
            bool: 发送是否成功
        """
        try:
            self.logger.info(f"📱 准备发送微信公众号通知: OpenID={user_openid[:8]}***, 商品数={len(products)}")

            if not products:
                self.logger.warning("❌ 商品列表为空，无法发送微信通知")
                return False
                
            # 导入微信服务
            from app.services.wechat_service import wechat_service
            
            # 调用微信服务发送模板消息
            success = await wechat_service.send_product_notification(
                openid=user_openid,
                products=products,
                notification_subject=notification_subject,
                monitor_type=monitor_type
            )
            
            if success:
                self.logger.info(f"✅ 微信通知发送成功: OpenID={user_openid[:8]}***, 商品={products[0].get('name', '')[:10]}...")
            else:
                self.logger.error(f"❌ 微信通知发送失败: OpenID={user_openid[:8]}***")
                
            return success

        except Exception as e:
            self.logger.error(f"❌ 微信公众号通知失败: {e}")
            return False

    async def send_telegram_notification(self, user_tg: str, products: List[Dict[str, Any]],
                                       notification_subject: str, monitor_type: str = "keyword") -> bool:
        """
        发送Telegram通知

        Args:
            user_tg: 用户Telegram ID或用户名
            products: 商品列表
            notification_subject: 通知主题（关键词或卖家信息）
            monitor_type: 监控类型（keyword或seller）

        Returns:
            bool: 发送是否成功
        """
        try:
            self.logger.info(f"📱 准备发送Telegram通知: TG={user_tg}, 商品数={len(products)}")
            
            # 使用Telegram服务发送通知
            return await self.telegram_service.send_product_notification(
                chat_id=user_tg,
                products=products,
                notification_subject=notification_subject,
                monitor_type=monitor_type
            )
            
        except Exception as e:
            self.logger.error(f"❌ Telegram通知发送失败: {e}")
            return False

    async def send_notification_by_channel(self, user: User, products: List[Dict[str, Any]],
                                         notification_subject: str, monitor_type: str = "keyword") -> bool:
        """
        根据用户配置的channel发送对应通知

        Args:
            user: 用户对象
            products: 商品列表
            notification_subject: 通知主题（关键词或卖家信息）
            monitor_type: 监控类型（keyword或seller）

        Returns:
            bool: 发送是否成功
        """
        try:
            channel = getattr(user, 'channel', 'EMAIL').upper()
            self.logger.info(f"📢 根据用户channel发送通知: {channel}, 用户ID={user.id}")
            
            if channel == 'EMAIL':
                if user.email:
                    return await self.send_product_notification(
                        user_email=user.email,
                        products=products,
                        notification_subject=notification_subject,
                        monitor_type=monitor_type
                    )
                else:
                    self.logger.warning(f"⚠️ 用户{user.id}未设置邮箱，无法发送邮件通知")
                    return False
                    
            elif channel == 'TG':
                user_tg = getattr(user, 'tg', None)
                if user_tg:
                    return await self.send_telegram_notification(
                        user_tg=user_tg,
                        products=products,
                        notification_subject=notification_subject,
                        monitor_type=monitor_type
                    )
                else:
                    self.logger.warning(f"⚠️ 用户{user.id}未设置Telegram ID，无法发送TG通知")
                    return False
                    
            elif channel == 'WECHAT':
                # 保持原有微信通知逻辑
                user_openid = getattr(user, 'openid', None)
                if user_openid:
                    return await self.send_wechat_notification(
                        user_openid=user_openid,
                        products=products,
                        notification_subject=notification_subject,
                        monitor_type=monitor_type
                    )
                else:
                    self.logger.warning(f"⚠️ 用户{user.id}未绑定微信，无法发送微信通知")
                    return False
                    
            else:
                self.logger.warning(f"⚠️ 不支持的通知渠道: {channel}，默认发送邮件通知")
                if user.email:
                    return await self.send_product_notification(
                        user_email=user.email,
                        products=products,
                        notification_subject=notification_subject,
                        monitor_type=monitor_type
                    )
                else:
                    self.logger.error(f"❌ 用户{user.id}邮箱为空，无法发送通知")
                    return False
                    
        except Exception as e:
            self.logger.error(f"❌ 根据channel发送通知失败: {e}")
            return False

    async def create_notification_record(self, db: AsyncSession, notification_data: NotificationCreate) -> Notification:
        """创建通知记录"""
        notification = Notification(**notification_data.dict())
        db.add(notification)
        await db.commit()
        await db.refresh(notification)
        return notification
    
    async def get_user_notifications(self, db: AsyncSession, user_id: int, limit: int = 50) -> List[Notification]:
        """获取用户通知记录"""
        result = await db.execute(
            select(Notification)
            .where(Notification.user_id == user_id)
            .order_by(Notification.created_at.desc())
            .limit(limit)
        )
        return result.scalars().all()
    
    async def mark_notification_read(self, db: AsyncSession, notification_id: int, user_id: int) -> bool:
        """标记通知为已读"""
        result = await db.execute(
            select(Notification).where(
                Notification.id == notification_id,
                Notification.user_id == user_id
            )
        )
        notification = result.scalar_one_or_none()
        
        if notification:
            notification.is_read = True
            notification.read_at = datetime.utcnow()
            await db.commit()
            return True
        
        return False
